package com.skillworld.webapp.model.util;

import com.skillworld.webapp.model.department.Department;
import com.skillworld.webapp.model.team.Team;
import com.skillworld.webapp.model.tutorial.Tutorial;
import com.skillworld.webapp.model.tutorial.Tutorial.Difficulty;
import com.skillworld.webapp.model.tutorial.Tutorial.Status;
import com.skillworld.webapp.model.user.User;

public class AssignPoints {

    private final static int POINTS_BY_TUT_ACCEPTED = 1;
    private final static int POINTS_BY_TUT_VALIDATED = 3;
    private final static int POINTS_BY_TUT_VALIDATION = 1;
    
    private final static int USER_POINTS_BY_TUT_EASY_DONE = 1;
    private final static int USER_POINTS_BY_TUT_MEDIUM_DONE = 2;
    private final static int USER_POINTS_BY_TUT_HARD_DONE = 3;
    private final static int AUTHOR_POINTS_BY_TUT_DONE = 2;
    
    private final static int NUM_TUT_TIMESDONE_TO_ADD_POINTS = 100;
    private final static int NUM_TUT_VOTES_TO_ADD_POINTS = 100;
    
    private Tutorial tutorial;
    private Department department;
    
    public AssignPoints(Tutorial tutorial) {
        this.tutorial = tutorial;
        this.department = tutorial.getDepartment();
    }
    
    protected void addAuthorPointsByTutorialAccepted(){
        this.getAuthor()
            .addPoints(POINTS_BY_TUT_ACCEPTED, department);
    }
    
    protected void addAuthorPointsByTutorialValidated(){
        this.getAuthor()
            .addPoints(POINTS_BY_TUT_VALIDATED, department);
    }
    
    protected void addValidatorPointsByValidation(){
        this.getValidator()
            .addPoints(POINTS_BY_TUT_VALIDATION, department);
    }
    
    public void addPointsByValidation(Status decision)
    {
        if(decision == Status.ACCEPTED){ 
            this.addAuthorPointsByTutorialAccepted();
        }else if(decision == Status.VALIDATED)
                { this.addAuthorPointsByTutorialValidated();}
        
        this.addValidatorPointsByValidation();
    }
    
    public void addPointsByRating(){
        if(canAddPointsByTutRate())
        {
            int rate = Math.round(new Float(tutorial.getRating()));
            int authorPoints = RatePoints.fromRate(rate);
            int teamPoints = RatePoints.teamPointsFromRate(rate);
            
            getAuthor().addPoints(authorPoints, department);
            
            for(Team t :getAuthor().getTeams()){
                t.addPoints(teamPoints);
            }
        }
    }
    
    public void addPointsUserByDoTutorial(User user){
        if(canAddPointsByTutDone())
        {
            getAuthor().addPoints(AUTHOR_POINTS_BY_TUT_DONE, department);
        }
        user.addPoints(getUserPointsByTutDone(), department);
    }
    
    protected int getUserPointsByTutDone(){
        int points = 0;
        Difficulty d = tutorial.getDifficulty();
        
        if(d == Difficulty.EASY)
        { points = USER_POINTS_BY_TUT_EASY_DONE;}
        else if(d == Difficulty.MEDIUM)
        { points = USER_POINTS_BY_TUT_MEDIUM_DONE;}
        else if(d == Difficulty.HARD)
        { points = USER_POINTS_BY_TUT_HARD_DONE;}
        
        return points;
    }
    
    protected boolean canAddPointsByTutRate(){
        return (tutorial.getVotes() % NUM_TUT_VOTES_TO_ADD_POINTS) == 0;
    }
    
    protected boolean canAddPointsByTutDone(){
        return (tutorial.getTimesDone() % NUM_TUT_TIMESDONE_TO_ADD_POINTS) == 0;
    }
    
    protected User getAuthor(){
        return tutorial.getAuthor();
    }
    
    protected User getValidator(){
        return tutorial.getValidator();
    }
}
